package com.zxbit.flash.ui.fragment;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.support.v4.widget.NestedScrollView;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.TextView;

import com.alibaba.android.arouter.launcher.ARouter;
import com.zhouwei.mzbanner.MZBannerView;
import com.zhouwei.mzbanner.holder.MZHolderCreator;
import com.zxbit.flash.PopApplication;
import com.zxbit.flash.R;
import com.zxbit.flash.cache.Acache;
import com.zxbit.flash.cache.AcacheKeys;
import com.zxbit.flash.adapter.BannerViewHolder;
import com.zxbit.flash.adapter.ProductAdapter;
import com.zxbit.flash.adapter.ProductAdapter.OnItemClickListener;
import com.zxbit.flash.base.BaseFragment;
import com.zxbit.flash.common.AuthRouter;
import com.zxbit.flash.common.Constant;
import com.zxbit.flash.common.DialogManager;
import com.zxbit.flash.common.RouterMap;
import com.zxbit.flash.common.UserInfo;
import com.zxbit.flash.mvpview.AlertDialogMvpView;
import com.zxbit.flash.mvpview.HomeMvpView;
import com.zxbit.flash.permission.IPermisson;
import com.zxbit.flash.permission.Permission;
import com.zxbit.flash.presenter.AlertDialogPresenter;
import com.zxbit.flash.presenter.HomePresenter;
import com.zxbit.flash.response.AlertDialogResponse;
import com.zxbit.flash.response.BannerResponse;
import com.zxbit.flash.bean.ProductItemData;
import com.zxbit.flash.bean.ProductListData;
import com.zxbit.flash.response.ProductResponse;
import com.zxbit.flash.bean.UserInformationData;
import com.zxbit.flash.response.UserInformationResponse;
import com.zxbit.flash.rxbus.EventMsg;
import com.zxbit.flash.rxbus.Events;
import com.zxbit.flash.rxbus.RxBus;
import com.zxbit.flash.utils.PXUtils;
import com.zxbit.flash.utils.StringUtils;
import com.zxbit.flash.utils.ToastUtils;
import com.zxbit.flash.view.dialog.GrantPermissionDialog;
import com.zxbit.flash.view.dialog.HomeOneDialog;
import com.zxbit.flash.view.dialog.HomeTwoDialog;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;

import static com.zxbit.flash.common.Constant.PROPERTY_ALPHA;
import static com.zxbit.flash.common.Constant.PROPERTY_SCALE_X;
import static com.zxbit.flash.common.Constant.PROPERTY_SCALE_Y;
import static com.zxbit.flash.common.Constant.PROPERTY_TRANSLATION_X;
import static com.zxbit.flash.common.Constant.PROPERTY_TRANSLATION_Y;

public class HomeFragment extends BaseFragment implements ViewTreeObserver.OnScrollChangedListener,
        OnItemClickListener, IPermisson, HomeMvpView, AlertDialogMvpView {

    @BindView(R.id.img_main_header)
    ImageView imgMainHeader; // 背景图片
    @BindView(R.id.iv_main_banner)
    ImageView ivMainBanner; // Banner占位图
    @BindView(R.id.layout_title_bg)
    View layoutTitleBg; // 标题栏背景
    @BindView(R.id.tv_title_reference)
    TextView tvTitleReference; // 标题参照物
    @BindView(R.id.tv_title)
    TextView tvTitle; // 标题
    @BindView(R.id.scroll_view)
    NestedScrollView scrollView;
    @BindView(R.id.banner)
    MZBannerView bannerView;
    @BindView(R.id.tv_data_empty)
    TextView tvDataEmpty;
    @BindView(R.id.rv_product)
    RecyclerView rvProduct;

    private HomePresenter homePresenter;
    private AlertDialogPresenter alertDialogPresenter;
    private Permission permission;
    private GrantPermissionDialog grantPermissionDialog;
    private ProductAdapter productAdapter;
    private HashMap<Integer, ProductListData> sourceData;
    private boolean isRemind = true; // 是否提醒还款

    private int isPerformAnimation; // 是否执行动画 0已执行 1还原动画
    private View showView; // 用于存放bannerView或者Banner占位图
    private int bannerTop; // bannerView或者Banner占位图到顶部的距离

    @Override
    public int getContentView() {
        return R.layout.fragment_home;
    }

    @SuppressLint("CheckResult")
    @Override
    public void onFragmentCreated(View rootView) {
        ButterKnife.bind(this, rootView);
        initView();
        initListener();
        checkAppPermission();
        RxBus.getInstance().toObservable().map(new Function<Object, EventMsg>() {
            @Override
            public EventMsg apply(Object o) throws Exception {
                return (EventMsg) o;
            }
        }).subscribe(new Consumer<EventMsg>() {
            @Override
            public void accept(EventMsg eventMsg) throws Exception {
                if (Events.LOGIN_SUCCESS.equals(eventMsg.getMsg()) || Events.LOGOUT.equals(eventMsg.getMsg())) {
                    homePresenter.getProduct();
                    showLoadingView();
                }
            }
        });
    }

    private void initView() {
        layoutTitleBg.setAlpha(0f);
        bannerTop = PXUtils.dp2px(getActivity(), 101);
        showView = ivMainBanner;
        scrollView.getViewTreeObserver().addOnScrollChangedListener(this);
        bannerView.setDelayedTime(5000);
        bannerView.setIndicatorVisible(true);
        rvProduct.setLayoutManager(new GridLayoutManager(getContext(), 2));
        rvProduct.setAdapter(getProductAdapter());
    }

    private void initListener() {
        homePresenter = new HomePresenter(this);
        alertDialogPresenter = new AlertDialogPresenter(this);
        homePresenter.getNotice();
    }

    @Override
    public void onResume() {
        super.onResume();
        if (UserInfo.isLogin() && isRemind) {
            alertDialogPresenter.getDialogInfo();
        }
    }

    private ProductAdapter getProductAdapter() {
        if (productAdapter == null) {
            productAdapter = new ProductAdapter(getActivity());
            productAdapter.setOnItemClickListener(this);
        }
        return productAdapter;
    }

    /**
     * 弹框并确认权限
     */
    private void checkAppPermission() {
        permission = new Permission((AppCompatActivity) getActivity(), this);
        String grant = Acache.get(PopApplication.getContext()).getAsString(AcacheKeys.GRANT);
        if (TextUtils.isEmpty(grant)) {
            if (grantPermissionDialog == null) {
                grantPermissionDialog = new GrantPermissionDialog(getActivity(), R.style.normal_dialog);
            }
            grantPermissionDialog.setOnClickListener(new GrantPermissionDialog
                    .GrantPermissionDialogCallBack() {
                @Override
                public void onConfirm() {
                    permission.requestAll();
                }

                @Override
                public void onCancel() {
                    DialogManager.getManager().dismissDialog(grantPermissionDialog);
                    getActivity().finish();
                }
            });
            DialogManager.getManager().showDialogStack(grantPermissionDialog);
        } else {
            sendUpdateMsg();
        }
    }

    @OnClick(R.id.tv_data_empty)
    public void onClick() {
        homePresenter.getProduct();
        showLoadingView();
    }

    @Override
    public void onItemClick(View view, int position, boolean lendStatus) {
        if (UserInfo.isLogin()) {
            if (!lendStatus) {
                ARouter.getInstance().build(RouterMap.LOANPAGE)
                        .withParcelable(Constant.LOAN_TERM_LIST, sourceData.get(position))
                        .navigation();
            } else {
                ToastUtils.showShort(getActivity(), getResources().getString(R.string.loan_level_too_low));
            }
        } else {
            ARouter.getInstance().build(RouterMap.FACEBOOKLOGIN).navigation();
            ToastUtils.showShort(getActivity(), getResources().getString(R.string.login_not_login));
        }
    }

    @Override
    public void onScrollChanged() {
        int scrollY = scrollView.getScrollY();
        float alpha = 1 - ((float) scrollY / (float) bannerTop);
        showView.setAlpha(alpha);
        if (scrollY > 108) {
            if (isPerformAnimation == 0) {
                performAnimation(isPerformAnimation);
            }
        } else {
            if (isPerformAnimation == 1) {
                performAnimation(isPerformAnimation);
            }
        }
    }

    /**
     * 滑动动画
     *
     * @param flag
     */
    private void performAnimation(int flag) {
        if (imgMainHeader == null || layoutTitleBg == null
                || tvTitleReference == null || tvTitle == null) return;

        AnimatorSet animatorSet = new AnimatorSet();
        isPerformAnimation = flag == 0 ? 1 : 0; // 表示执行或还原过动画,避免重复执行
        float[] right = flag == 0 ? new float[]{0, tvTitleReference.getLeft() - tvTitle.getLeft()}
                : new float[]{tvTitleReference.getLeft() - tvTitle.getLeft(), 0};
        float[] top = flag == 0 ? new float[]{0, tvTitleReference.getTop() - tvTitle.getTop()}
                : new float[]{tvTitleReference.getTop() - tvTitle.getTop(), 0};
        float[] titleAlpha = flag == 0 ? new float[]{0f, 1f} : new float[]{1f, 0f};
        float[] bgAlpha = flag == 0 ? new float[]{1f, 0f} : new float[]{0f, 1f};
        float[] scaleX = flag == 0 ? new float[]{1f, 1.5f} : new float[]{1.5f, 1f};
        float[] scaleY = flag == 0 ? new float[]{1f, 1.5f} : new float[]{1.5f, 1f};
        animatorSet.playTogether(
                ObjectAnimator.ofFloat(tvTitle, PROPERTY_TRANSLATION_X, right).setDuration(400),
                ObjectAnimator.ofFloat(tvTitle, PROPERTY_TRANSLATION_Y, top).setDuration(400),
                ObjectAnimator.ofFloat(layoutTitleBg, PROPERTY_ALPHA, titleAlpha).setDuration(800),
                ObjectAnimator.ofFloat(imgMainHeader, PROPERTY_ALPHA, bgAlpha).setDuration(800),
                ObjectAnimator.ofFloat(imgMainHeader, PROPERTY_SCALE_X, scaleX).setDuration(800),
                ObjectAnimator.ofFloat(imgMainHeader, PROPERTY_SCALE_Y, scaleY).setDuration(800)
        );
        animatorSet.start();
    }

    /**
     * 获取权限
     */
    @Override
    public void onSuccess(int result) {
        if (result == 1) {
            Acache.get(PopApplication.getContext()).put(AcacheKeys.GRANT, "1");
            DialogManager.getManager().dismissDialog(grantPermissionDialog);
            sendUpdateMsg();
        }
    }

    public void sendUpdateMsg() {
        EventMsg eventMsg = new EventMsg();
        eventMsg.setMsg(Events.UPDATE);
        RxBus.getInstance().post(eventMsg);
        homePresenter.getProduct();
        showLoadingView();
    }

    @Override
    public void onGetDataNext(final AlertDialogResponse response) {
        if (response.getStatus() == Constant.HTTP_OK) {
            //资料退回
            if ("1".equals(response.getData().getCode())) {
                final HomeOneDialog homeOneDialog = new HomeOneDialog(getActivity(), R.style.normal_dialog);
                homeOneDialog.setTitle(getStringResource(R.string.main_dialog_order_back));
                homeOneDialog.setContent(getStringResource(R.string.main_dialog_order_back_message));
                homeOneDialog.setEason(getStringResource(R.string.main_dialog_order_back_error_message) + response.getData()
                        .getOrderBackReason());
                homeOneDialog.setButtonStr(getStringResource(R.string.main_dialog_order_back_button_text));
                homeOneDialog.setOneClickListener(new HomeOneDialog.OneClickListener() {
                    @Override
                    public void onConfirm() {
                        homePresenter.getPersonInfoBack(response.getData().getUserUUID());
                        DialogManager.getManager().dismissDialog(homeOneDialog);
                    }
                });
                DialogManager.getManager().showDialogStack(homeOneDialog);
            } else if ("4".equals(response.getData().getCode())) {
                //换绑银行卡
                String error_message = getStringResource(R.string.main_dialog_bank_card_failt_message);
                error_message = String.format(error_message, response.getData().getOrderCrtTime());
                final HomeOneDialog homeOneDialog = new HomeOneDialog(getActivity(), R.style.normal_dialog);
                homeOneDialog.setTitle(getStringResource(R.string.main_dialog_bank_card_failt));
                homeOneDialog.setContent(error_message);
                homeOneDialog.setEason(getStringResource(R.string.main_dialog_bank_card_failt_error_message));
                homeOneDialog.setButtonStr(getStringResource(R.string
                        .main_dialog_bank_card_change));
                homeOneDialog.setOneClickListener(new HomeOneDialog.OneClickListener() {
                    @Override
                    public void onConfirm() {
                        ARouter.getInstance().build(RouterMap.BANK_AUTH_PAGE).withBoolean
                                (Constant.IS_CHANGE, true).navigation();
                        DialogManager.getManager().dismissDialog(homeOneDialog);
                    }
                });
                DialogManager.getManager().showDialogStack(homeOneDialog);
            } else if ("5".equals(response.getData().getCode())) {
                //放款成功
                String successMessage = getStringResource(R.string.main_dialog_borrow_success_message);
                successMessage = String.format(successMessage, response.getData().getOrderCrtTime());
                final HomeOneDialog homeOneDialog = new HomeOneDialog(getActivity(), R.style.normal_dialog);
                homeOneDialog.setTitle(getStringResource(R.string.main_dialog_borrow_success));
                homeOneDialog.setContent(successMessage);
                homeOneDialog.setEason("");
                homeOneDialog.setButtonStr(getStringResource(R.string.main_dialog_repay_cancel_text));
                homeOneDialog.setOneClickListener(new HomeOneDialog.OneClickListener() {
                    @Override
                    public void onConfirm() {
                        DialogManager.getManager().dismissDialog(homeOneDialog);
                    }
                });
                DialogManager.getManager().showDialogStack(homeOneDialog);
            } else if ("6".equals(response.getData().getCode()) || "7".equals(response.getData().getCode())) {
                final HomeTwoDialog homeTwoDialog = new HomeTwoDialog(getActivity(), R.style.normal_dialog);
                homeTwoDialog.setTwoClickListener(new HomeTwoDialog.TwoClickListener() {
                    @Override
                    public void onConfirm() {
                        isRemind = false;
                        DialogManager.getManager().dismissDialog(homeTwoDialog);
                    }

                    @Override
                    public void onRepayment() {
                        ARouter.getInstance().build(RouterMap.REPAY_METHOD_PAGE)
                                .withString(Constant.ORDER_ID, response.getData().getOrderId())
                                .withString(Constant.ORDER_MONEY_NUM, response.getData().getRepayAmt().toString())
                                .navigation();
                        DialogManager.getManager().dismissDialog(homeTwoDialog);
                    }
                });
                homeTwoDialog.setAlertDialogData(response.getData());
                if ("6".equals(response.getData().getCode())) {
                    //还款提醒
                    homeTwoDialog.setType(6);
                } else {
                    //逾期提醒
                    homeTwoDialog.setType(7);
                }
                DialogManager.getManager().showDialogStack(homeTwoDialog);
            }
        } else {
            ToastUtils.showShort(getActivity(), response.getMessage());
        }
    }

    @Override
    public void onGetDataNext(UserInformationResponse response) {
        final UserInformationData data = response.getData();
        if (data.getIsInformationWrong() == Constant.USER_DATA_BACK) {
            if (!StringUtils.isEmpty(data.getAuthPageCode())) {
                Acache.get(PopApplication.getContext()).put(AcacheKeys.BACK, data.getUserUuid());
                //把uuid 保存起来
                AuthRouter.getInstance().backRouter(response.getData().getAuthPageCode());
            }
        } else {
            Acache.get(PopApplication.getContext()).put(AcacheKeys.BACK, "");
        }
    }

    @Override
    public void onGetDataNext(BannerResponse response) {
        if (response.getStatus() == Constant.HTTP_OK) {
            if (response.hasData()) {
                replaceBannerView(bannerView);
                bannerView.setPages(response.getData(), new MZHolderCreator<BannerViewHolder>() {
                    @Override
                    public BannerViewHolder createViewHolder() {
                        return new BannerViewHolder();
                    }
                });
                if (response.getData().size() > 1) {
                    bannerView.start();
                } else {
                    bannerView.setCanLoop(false);
                }
            } else {
                replaceBannerView(ivMainBanner);
            }
        } else {
            ToastUtils.showShort(getActivity(), response.getMessage());
        }
    }

    // 替换BannerView
    private void replaceBannerView(View view) {
        if (showView.getId() == view.getId()) return;
        float alpha = showView.getAlpha();
        view.setVisibility(View.VISIBLE);
        showView = view;
        showView.setAlpha(alpha);
        switch (view.getId()) {
            case R.id.iv_main_banner:
                bannerView.setVisibility(View.GONE);
                break;
            case R.id.banner:
                ivMainBanner.setVisibility(View.GONE);
                break;
        }
    }

    @Override
    public void onGetDataNext(ProductResponse response) {
        dismissLoadingView();
        if (response.getStatus() == Constant.HTTP_OK) {
            if (response.hasData()) {
                tvDataEmpty.setVisibility(View.GONE);
                rvProduct.setVisibility(View.VISIBLE);
                ArrayList<ProductItemData> list = getShowList(response.getData());
                getProductAdapter().updateItems(list);
                for (int i = 0; i < list.size(); i++) {
                    if (!"1".equals(list.get(i).getLendStatus())) {
                        getProductAdapter().setSelect(i);
                        break;
                    }
                }
            } else {
                getProductAdapter().removeAllItems();
                tvDataEmpty.setVisibility(View.VISIBLE);
            }
        } else {
            ToastUtils.showShort(getActivity(), response.getMessage());
        }
    }

    /**
     * 获取显示的Product（排重）
     */
    @SuppressLint("UseSparseArrays")
    private ArrayList<ProductItemData> getShowList(List<ProductItemData> data) {
        ArrayList<ProductItemData> list = new ArrayList<>();
        if (sourceData == null) {
            sourceData = new HashMap<>();
        } else {
            sourceData.clear();
        }
        for (int i = 0; i < data.size(); i++) {
            ProductItemData itemData = data.get(i);
            int index = isContainProduct(list, data.get(i).getPRange());
            if (index == -1) {
                list.add(itemData);
                ProductListData productListData = new ProductListData();
                productListData.setpRange(String.valueOf(itemData.getPRange()));
                ArrayList<ProductItemData> pList = new ArrayList<>();
                pList.add(itemData);
                productListData.setpList(pList);
                sourceData.put(list.indexOf(itemData), productListData);
            } else {
                sourceData.get(index).getpList().add(itemData);
                // 数据源中尽量添加可借款项
                if (!"1".equals(itemData.getLendStatus()) && "1".equals(list.get(index).getLendStatus())) {
                    list.add(index, itemData);
                    list.remove(index + 1);
                }
            }
        }
        return list;
    }

    // 排重方法 by pRange
    private int isContainProduct(List<ProductItemData> list, int pRange) {
        for (int i = 0; i < list.size(); i++) {
            if (pRange == list.get(i).getPRange())
                return i;
        }
        return -1;
    }

    @Override
    public void onGetDataError(Throwable throwable) {
//        if (!(throwable instanceof JsonSyntaxException)) {
//            tvDataEmpty.setVisibility(View.VISIBLE);
//            rvProduct.setVisibility(View.GONE);
//        }
        dismissLoadingView();
    }

    @Override
    public void onFragmentDestoryed() {
    }

}
